001    /**
002     * Created by IntelliJ IDEA.
003     * User: Wei Wang
004     * Date: Nov 30, 2002
005     * Time: 2:13:56 PM
006     */
007    
008    package EVolve.visualization.XYViz.ValValViz;
009    
010    import EVolve.util.*;
011    import EVolve.util.painters.RandomPainter;
012    import EVolve.data.*;
013    import EVolve.visualization.*;
014    import EVolve.visualization.Dimension;
015    import EVolve.Scene;
016    import javax.swing.*;
017    import java.util.*;
018    import java.awt.event.*;
019    import java.awt.*;
020    
021    public class StackViz extends ValueValueVisualization{
022        private ArrayList menuList;
023        private JMenuItem itemChangeThread;
024        private HashMap methodStacks;
025        private ThreadChooser td;
026        private JTextField textBegin, textEnd;
027        private Stack stack;
028        private int event;
029        private JMenuItem itemSelectTimeFrame, itemSelectOccurredEntities;
030        private static JMenuItem selectionMenu[] = null;
031        private String selected;
032        protected static int SELECT_OPTION = 0x0011;
033        private JLabel toEventNo;
034    
035    
036        public StackViz() {
037            super();
038    
039            menuList = new ArrayList();
040            imageMap = new HashMap();
041            methodStacks = new HashMap();
042            td = new ThreadChooser(imageMap,false);
043    
044            interval = 1;
045            beginCall = 0;
046            endCall = 300;
047        }
048    
049        public Dimension[] createDimension() {
050            Dimension [] returnDimension = new Dimension[3];
051    
052            xAxis = new ValueDimension();
053            entityIdFilter = new ReferenceDimension();
054            filter2 = new ReferenceDimension();
055    
056            returnDimension[0] = xAxis;
057            returnDimension[1] = entityIdFilter;
058            returnDimension[2] = filter2;
059    
060            return returnDimension;
061        }
062    
063        protected void updateConfiguration() {
064            try {
065                beginCall = Integer.parseInt(textBegin.getText());
066                endCall = Integer.parseInt(textEnd.getText());
067    
068                canvas.setName("Time - Invocations", "Stack");
069                super.updateConfiguration();
070            } catch (NumberFormatException e) {
071                Scene.showErrorMessage("Begin call and end call must be an integer and smaller than "+Integer.MAX_VALUE+".");
072                configure();
073            };
074        }
075    
076        public HashMap getCurrentConfigure() {
077            HashMap configure = super.getCurrentConfigure();
078    
079            configure.put("Interval", new Integer(interval));
080            configure.put("BeginCall", new Long(beginCall));
081            configure.put("EndCall", new Long(endCall));
082    
083            return configure;
084        }
085    
086        public void preVisualize() {
087            xMax = 0;
088            event = 0;
089            stack = null;
090            image = null;
091            imageMap.clear();
092            methodStacks.clear();
093            currentThread = -1;
094            getSelection();
095            installPainter();
096            super.preVisualize();
097        }
098    
099        public void receiveElement(Element element) {
100            long methodId = entityIdFilter.getField(element);
101            long threadId = filter2.getField(element);
102            long callno = xAxis.getField(element) - 1;
103    
104            countEvents(callno/2);
105    
106            switchThread(threadId);
107    
108            if ((callno<beginCall*2) || (callno>endCall*2+1)) {
109                if (element.isOptional()) {// method return;
110                    if (!stack.empty()) stack.pop();
111                } else
112                    stack.push(new Long(methodId));
113                return;
114            }
115    
116            event++;
117            if (!element.isOptional()) // method enter;
118                stack.push(new Long(methodId));
119    
120            for (int j=0;j<stack.size();j++) {
121                painter.paint(image,callno-beginCall*2,j,((Long)stack.get(j)).intValue());
122            }
123    
124            if (element.isOptional()) {// method return;
125                if (!stack.empty()) stack.pop();
126            }
127        }
128    
129        public void visualize() {
130            if (imageMap.size() == 0 ) return;
131            while (selected==null) {
132                selected = td.showDialog();
133                if (selected != null) {
134                    image = (AutoImage)imageMap.get(new Long(selected.substring(7,selected.length())));
135                    canvas.setName("Time - "+ xAxis.getDataFilter().getName() + "(" + event/2 +" events)", "Stack");
136                    sort();
137                    selected = null;
138                    break;
139                }
140            }
141        }
142    
143        public void makeSelection() {
144            if (SELECT_OPTION == 0) {
145                Scene.showErrorMessage("No data is to be selected.");
146                return;
147            }
148    
149            if (dataSourceId != Scene.getDataSourceManager().getCurrentDataSourceId()) {
150                Scene.showErrorMessage("The active data source used currently is different from \n" +
151                                       "this visualization, please choose \"" +
152                                       Scene.getDataSourceManager().getUsedDataSourceName(dataSourceId)+"\".");
153                return;
154            }
155    
156            int x1 = canvas.getStartX();
157            int x2 = canvas.getEndX();
158            int y1 = canvas.getEndY();
159            int y2 = canvas.getStartY();
160    
161            if (!normalOrientation) {
162                int temp;
163                temp = x1;
164                x1 = y1;
165                y1 = temp;
166                temp = x2;
167                x2 = y2;
168                y2 = temp;
169            }
170    
171            if (((x1<0)&&(x2<0)) || ((x1/2>=timeMap.size()))&&(x2/2>=timeMap.size()))
172               return;
173    
174            if (x1 < 0) x1 = 0;
175    
176            if (x2/2 > timeMap.size())
177                x2 = (timeMap.size()-1)*2;
178    
179    
180            long start, end;
181            if ((SELECT_OPTION & 0x000f) == 0) {
182                start = 0;
183                end = Long.MAX_VALUE;
184            } else {
185                long eventInterval[] = (long[])timeMap.get((int)(x1/2+beginCall));
186                start = eventInterval[1];
187                eventInterval = (long[])timeMap.get((int)(x2/2+beginCall));
188                end = eventInterval[1];
189            }
190    
191            if (y1 < 0) y1 = 0;
192    
193            int methodId;
194            ArrayList idList = new ArrayList();
195            for (int i = x1; i <= x2; i++) {
196                for (int j = y1; j <= y2; j++) {
197                    if (normalOrientation)
198                        methodId = (int)getEntityId(i,j);
199                    else
200                        methodId = (int)getEntityId(j,i);
201                    if ((methodId == -1)||(idList.contains(new Integer(methodId)))) continue;
202                    idList.add(new Integer(methodId));
203                }
204            }
205    
206    
207            int selection[] = null;
208    
209            if ((SELECT_OPTION & 0x00f0) == 0x0010) {
210                selection = new int[idList.size()];
211                for (int i=0; i<selection.length; i++)
212                    selection[i] = ((Integer)idList.get(i)).intValue();
213            } else {
214                selection = new int[entityIdFilter.getEntityNumber()];
215                for (int i=0; i<selection.length; i++)
216                    selection[i] = i;
217            }
218    
219            entityIdFilter.makeSelection(subjectDefinition.getType(),selection,start,end,timeMap);
220        }
221    
222        protected void mouseMove(int x, int y) {
223            int X = canvas.getImageX(x);
224            int Y = canvas.getImageY(y);
225    
226            if ((X>=0) && (Y >= 0)) {
227                if (image.getSortedColor(null,null,X,Y)==null)
228                    Scene.setStatus("  ");
229                else
230                    Scene.setStatus(getEntityName(X,Y)+" "+X+":"+Y);
231            } else {
232                Scene.setStatus(" ");
233            }
234        }
235    
236        protected ArrayList createOptionalMenu() {
237            if (menuList.size() > 0) return null;
238    
239            menuList.clear();
240            itemChangeThread = new JMenuItem("Switch thread...");
241            itemChangeThread.setMnemonic(KeyEvent.VK_T);
242            itemChangeThread.addActionListener(new ActionListener() {
243                public void actionPerformed(ActionEvent e) {
244                    visualize();
245                }
246            });
247    
248            menuList.add(itemChangeThread);
249            return menuList;
250        }
251    
252        private String getEntityName(int x, int y) {
253            String returnVal = "";
254            int mappedId = (int)getEntityId(x,y);
255            Entity entity = entityIdFilter.getEntityFromInt(mappedId);
256    
257            if (entity != null) returnVal = entity.getName();
258            return returnVal;
259        }
260    
261        private long getEntityId(int x, int y) {
262            Color color = image.getSortedColor(null,null,x,y);
263            if ((color == null)||(painter == null)) return -1;
264            return ((RandomPainter)painter).getKeyFromColor(color);
265        }
266    
267        protected void switchThread(long threadId) {
268            if (currentThread != threadId) {
269                stack = (Stack)methodStacks.get(new Long(threadId));
270                if (stack == null) {
271                    stack = new Stack();
272                    methodStacks.put(new Long(threadId),stack);
273                }
274                super.switchThread(threadId);
275            }
276        }
277    
278        protected void installPainter() {
279            painter = new RandomPainter();
280        }
281    
282        public JMenuItem[] createSelectionMenuItem() {
283            if (selectionMenu!=null) return selectionMenu;
284    
285            itemSelectTimeFrame = new JCheckBoxMenuItem("Time Frame");
286            itemSelectTimeFrame.setMnemonic(KeyEvent.VK_T);
287            itemSelectTimeFrame.addActionListener(new ActionListener() {
288                public void actionPerformed(ActionEvent e) {
289                    boolean selected = itemSelectTimeFrame.isSelected();
290                    SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_TIME_FRAME);
291                }
292            });
293            itemSelectTimeFrame.setSelected(true);
294    
295            itemSelectOccurredEntities = new JCheckBoxMenuItem("Occurred Entities");
296            itemSelectOccurredEntities.setMnemonic(KeyEvent.VK_O);
297            itemSelectOccurredEntities.addActionListener(new ActionListener() {
298                public void actionPerformed(ActionEvent e) {
299                    boolean selected = itemSelectOccurredEntities.isSelected();
300                    SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_OCCURRED_ENTITIES);
301                }
302            });
303            itemSelectOccurredEntities.setSelected(true);
304    
305            selectionMenu = new JMenuItem[2];
306            selectionMenu[0] = itemSelectTimeFrame;
307            selectionMenu[1] = itemSelectOccurredEntities;
308    
309            return selectionMenu;
310        }
311    
312        protected JPanel createConfigurationPanel() {
313            JPanel returnVal = new JPanel(new GridLayout(1, 1, 5, 5));
314            JPanel panelEvent = new JPanel(new GridLayout(2,2));
315    
316            Box panelBottom = new Box(BoxLayout.Y_AXIS);
317            returnVal.add(panelBottom);
318    
319            textBegin = new JTextField(String.valueOf(beginCall));
320            textEnd = new JTextField(String.valueOf(endCall));
321            panelEvent.add(new JLabel("From Call No:"));
322            panelEvent.add(textBegin);
323    
324            toEventNo = new JLabel("To Call No:");
325            panelEvent.add(toEventNo);
326            panelEvent.add(textEnd);
327            panelBottom.add(panelEvent);
328    
329            return returnVal;
330        }
331    
332        protected void updateComboSubject() {
333            super.updateComboSubject();
334            String range = String.valueOf(Scene.getDataManager().getDataSource().getNumberOfEvents(elementDefinition[comboSubject.getSelectedIndex()].getName()));
335            toEventNo.setText("To Call No:("+range+")");
336        }
337    
338        public Object clone() {
339            StackViz o = (StackViz)super.clone();
340            o.dimension[0] = o.xAxis;
341            o.dimension[1] = o.entityIdFilter;
342            o.dimension[2] = o.filter2;
343    
344    
345            o.td = new ThreadChooser(o.imageMap,false);
346    
347            o.methodStacks = new HashMap();
348            Iterator it = methodStacks.keySet().iterator();
349            while (it.hasNext()) {
350                Object key = it.next();
351                Stack newStack = new Stack(), oldStack = (Stack)methodStacks.get(key);
352                o.methodStacks.put(key,newStack);
353                for (int i=0; i<oldStack.size(); i++)
354                    newStack.add(oldStack.get(i));
355            }
356    
357            o.menuList = new ArrayList();
358            o.createDialog();
359            return o;
360        }
361    
362    }